// ==================================================================================
// Shared Genomics Project MPI Codebase
// Version 1.0 30/04/2010
//
// (c) 2010 University of Manchester all rights reserved
//
// This file is distributed under the GNU General Public License, Version 2.  
// Please see the file COPYING.txt for more details
// ==================================================================================

#ifndef _BPEDFILE_H_
#define _BPEDFILE_H_

#include "mapfile.h"
#include "options.h"
#include "pedfile.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
\file
\ingroup	gio
\brief		Binary Pedigree File (BPED)
\details
	A binary pedigree file (BPED) is SNP-major.<br>
	The pedigree information of the \ref csnp::one and 
	\ref csnp::two arrays of each SNP in a data-set (\ref mapfile) is combined into alternate positions
	within the byte array.<br>
	Data access is done by reading the binary file and using standard pointer arithmetic to 
	access the information (dimensions=nSNP * nSamples * 2).<br>
	The binary pedigree file uses the file suffix \ref SUFFIX_BPED_FILE.<br>
	The I/O BPED filename is bound to  \ref selected_options::szBpedFileName when read as a command-line parameter.
\see csnp
*/

/*! 
\brief Create a binary pedigree file. 
\details 
	Function encodes the pedigree information from a \ref mapfile into a simpler
	byte array form and writes that data to a binary file.<br>
	Output filename is a concatonation of \ref selected_options::ldir, 
	\ref selected_options::szRunId and \ref SUFFIX_BPED_FILE .
\param [in] ops Output location
\param [in] m Populated genomic data-set
\return 1 if successful, 0 if failure
*/
int bpedfile_create(struct selected_options *ops, struct mapfile *m);

/*!
\brief Reads the header information of a binary PED file 
\param [in, out] bin binary input handle to an 'opened' BPED file.
\param [in, out] nSNPs Pointer to write the No. SNPs in the file.
\param [in, out] nSamples Pointer to write the No. Samples/People in the file.
*/
int bpedfile_read_header(FILE *bin, int *nSNPs, int *nSamples);

/*!
\brief Read a fragment from binary PED file
\details
	Reads a fragment of a BPED data for a file of size SNPs x 2 x Samples.<br>
	Fragment reads can start from zero to nth SNP position (standard 'C' substring access).<br>
\param [in,out] bin binary input handle to an 'opened' BPED file.
\param [in] nSNPs No. SNPs
\param [in] nSamples No. Samples/People
\param [in] start index of SNP to read from
\param [in] end limit of SNPs to read to 
\returns char/byte array or NULL on failure
*/
char* bpedfile_fseek(FILE *bin, int nSNPs, int nSamples, int start, int end);

/*!
\brief Write a filtered BPED fragment to file.
\details
	If a fragment of BPED data is filtered, certain SNPs and samples/persons are removed 
	from the byte array (bpedData).<br>
	This function writes the fragment of filtered BPED data to file.<br>
	The output filename is a concatonation of \ref selected_options::szRunId and \ref SUFFIX_FBPED_FILE .<br>
	An output file is created locally then copied to a remote directory.<br>
	If all the SNPs/people removed data-set fragment, function call will fail.
\param [in] bpedData A fragment of 'raw' BPED data.
\param [in] nSNPs No. SNPs in bpedData
\param [in] nSamples No. Samples/People in bpedData
\param [in] snps_to_del SNP indices to remove from bpedData
\param [in] persons_to_del person/sample to remove from bpedData
\param [in] rank Processor rank
\param [in] ops Output location
\param [in] ldir Local Working directory
\param [in] rdir Remote Working directory
\see bpedfile_fseek
\bug Not sure if total removal of all data-set entries sensible design rule for this function.
*/
int bpedfile_write_filtered(char *bpedData, int nSNPs, int nSamples, BOOL *snps_to_del, BOOL *persons_to_del, int rank, struct selected_options *ops, char *ldir, char *rdir);

/*!
\brief Reads a filtered BPED fragment from file.
\details
	The input file name is a concatonation of \ref selected_options::szRunId, 
	\ref SUFFIX_FBPED_FILE and a processor rank.<br>
	A input file is copied from a remote directory and read locally.
\param [in,out] buffer Buffer for the 'filtered' BPED data
\param [in] rank Processor rank
\param [in] ops Input location
\param [in] ldir Local Working directory
\param [in] rdir Remote Working directory
\returns Amount of data read from file (zero on failure)
*/
size_t bpedfile_read_filtered(char *buffer, int rank, struct selected_options *ops, char *ldir, char *rdir);

/*!
\brief Write a summary of about the contents of a genomic data-set.
\details
	Functions scans the contents of a genomic data-set (see \ref mapfile),
	counts the missing values for SNPs and people then writes the min, median and max
	missingness values to a text file.<br>
	Output filename is a concatonation of \ref selected_options::szRunId and \ref SUFFIX_BPED_SUMMARY .<br>
	An output file is created locally then copied to a remote directory.
*/
int bpedfile_write_summary_and_copy(struct selected_options *ops, struct mapfile *m);

/*! 
\brief Create a binary pedigree file and copy to a remote directory.
\details
	The output filename is a concatonation of \ref selected_options::rdir, \ref selected_options::szRunId
	and \ref SUFFIX_BPED_FILE .<br>
\param [in] ops Output file location
\param [in] m Genomic data-set
\param [in] rank Local processor rank
\return 1 on success, 0 on failure
*/
int bpedfile_create_and_copy(struct selected_options *ops, struct mapfile *m, int rank);

/*! 
\brief Read an entire BPED file into memory.
\details
	The input file path is bound to the variable \ref selected_options::szBpedFileName.
\param [in] ops input file location
\param [in] nSNPs Pointer to integer to store No. SNPs
\param [in] nSamples Pointer to integer to store No. Samples
\return char array of BPED data or NULL on failure
*/
char* bpedfile_load(struct selected_options *ops, int *nSNPs, int *nSamples);

/*!
\brief Read a chunk of filtered pedigree data from a remote directory.
\details
	The input file path is a concatonation of \ref selected_options::rdir,
	\ref selected_options::szRunId, rank and \ref SUFFIX_FBPED_FILE.

\param [in] ops input file location
\param [in] rank Rank or processor number to read data
\return char array of BPED data or NULL on failure
*/
char* _bpedfile_read_filtered(struct selected_options *ops, int rank);

#ifdef __cplusplus
}
#endif

#endif // _BPEDFILE_H_
